package com.woniuxy.moneyapp.service.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.moneyapp.infra.dto.CoachToParam;
import com.woniuxy.moneyapp.infra.dto.VenueDetails;
import com.woniuxy.moneyapp.infra.dto.VenueLocation;
import com.woniuxy.moneyapp.service.PeopleNearbyService;
import com.woniuxy.signing.client.CocahSigningVenueClient;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class PeopleNearbyServiceImpl implements PeopleNearbyService {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;


    private ObjectMapper om = new ObjectMapper();

    @Resource
    private CocahSigningVenueClient csvc;

    //GEO相关命令用到的KEY
    private final static String KEY = "venue_point:";

    //增
    //地理位置
    @Override
    public boolean saveVenueLocation(VenueLocation venue) {
        Long flag = redisTemplate.opsForGeo().add(KEY, new RedisGeoCommands.GeoLocation<>(
                venue.getId()+"",
                new Point(venue.getVenueLg(), venue.getVenueLa()))
        );
        boolean result = flag != null && flag > 0;
        return result;
    }
    //场馆详细信息 VenueToShowOnMap:"+vds.getVenueId()
    @Override
    public boolean saveVenueInfo(VenueDetails vds) throws JsonProcessingException {
        //用场馆id存 VenueToShowOnMap:1
        redisTemplate.opsForValue().set("VenueToShowOnMap:"+vds.getId(),om.writeValueAsString(vds));
        return true;
    }
    //教练详细信息 "CoachToShow:"+vds.getVenueId()
    @Override
    public boolean saveCoachInfo(CoachToParam ctp) throws JsonProcessingException {
        redisTemplate.opsForValue().set("CoachToShow:"+ctp.getId(),om.writeValueAsString(ctp));
        return true;
    }
    //查
    @Override
    public List<VenueLocation> findVenueByCondition(double distance, double userLng, double userLat) {
        List<VenueLocation> venues = new ArrayList<>();
        Distance distanceArg = new Distance(distance, Metrics.KILOMETERS);
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs()
                .includeDistance()
                .includeCoordinates().sortAscending();
        // 1.GEORADIUS获取附近范围内的信息
        GeoResults<RedisGeoCommands.GeoLocation<Object>> reslut =
                redisTemplate.opsForGeo().radius(KEY, new Circle(new Point(userLng, userLat), distanceArg), args);
        //2.收集信息，存入list
        List<GeoResult<RedisGeoCommands.GeoLocation<Object>>> content = reslut.getContent();
        //3.返回计算后的信息
        content.forEach(a -> venues.add(new VenueLocation().setId(Integer.parseInt(a.getContent().getName().toString()))
                                    .setDistance(a.getDistance().getValue() * 1000)
                                    .setVenueLa(a.getContent().getPoint().getX())
                                    .setVenueLg(a.getContent().getPoint().getY())));
        return venues;

    }

    @Override
    public void deleteCoashInfo(Integer cid) {
        redisTemplate.delete("CoachToShow:"+cid);
    }

    @Override
    public void deleteVenueInfo(Integer vid) {
        redisTemplate.delete("CoachToShow:"+vid);
    }


}
